using System;
using System.Collections.Generic;
using System.Net;
using CodePlex.TfsLibrary.RepositoryWebSvc;

namespace CodePlex.UnitTestUtility
{
    public class StubRepositoryWebSvc : IRepositoryWebSvc
    {
        public CheckinNotificationInfo CheckIn_CheckinNotificationInfo;
        public CheckinOptions CheckIn_CheckinOptions;
        public List<Failure> CheckIn_Failures;
        public Changeset CheckIn_Info;
        public string CheckIn_OwnerName;
        public CheckinResult CheckIn_Result;
        public List<string> CheckIn_ServerItems;
        public string CheckIn_WorkspaceName;

        public Exception CreateWorkspace_Throw = null;
        public Workspace CreateWorkspace_Workspace;
        ICredentials credentials;

        public string DeleteWorkspace_Owner;
        public string DeleteWorkspace_WorkspaceName;

        public bool Get_Force;
        public GetRequest[] Get_GetRequests;
        public bool Get_NoGet;
        public string Get_OwnerName;
        public List<GetOperation> Get_Result = new List<GetOperation>();
        public string Get_WorkspaceName;

        public RepositoryProperties GetRepositoryProperties__Result;

        public ChangeRequest[] PendChanges_Changes;
        public Failure[] PendChanges_Failures;
        public string PendChanges_OwnerName;
        public GetOperation[] PendChanges_Result;
        public string PendChanges_WorkspaceName;
        public bool QueryHistory_GenerateDownloadUrls;
        public bool QueryHistory_IncludeFiles;

        public ItemSpec QueryHistory_ItemSpec;
        public int QueryHistory_MaxCount;
        public Changeset[] QueryHistory_Result;
        public bool QueryHistory_SlotMode;
        public string QueryHistory_User;
        public VersionSpec QueryHistory_VersionFrom;
        public VersionSpec QueryHistory_VersionItem;
        public VersionSpec QueryHistory_VersionTo;
        public string QueryHistory_WorkspaceName;
        public string QueryHistory_WorkspaceOwner;
        public DeletedState QueryItems_DeletedState;
        public bool QueryItems_GenerateDownloadUrls;
        public ItemSpec[] QueryItems_Items;
        public ItemType QueryItems_ItemType;
        public string QueryItems_Owner;
        public ItemSet[] QueryItems_Result;
        public VersionSpec QueryItems_Version;
        public string QueryItems_WorkspaceName;

        public int QueryItemsById_ChangeSet;
        public bool QueryItemsById_GenerateDownloadUrls;
        public int[] QueryItemsById_ItemIds;
        public Item[] QueryItemsById_Result;

        public string QueryWorkspace_Owner;
        public string QueryWorkspace_WorkspaceName;
        public string QueryWorkspaces_Computer;
        public string QueryWorkspaces_Owner;
        public Workspace[] QueryWorkspaces_Result;

        public Failure[] UndoPendingChanges_Failures;
        public ItemSpec[] UndoPendingChanges_Items;
        public string UndoPendingChanges_OwnerName;
        public GetOperation[] UndoPendingChanges_Result;
        public string UndoPendingChanges_WorkspaceName;

        public string UpdateLocalVersion_OwnerName;
        public LocalVersionUpdate[] UpdateLocalVersion_Updates;
        public string UpdateLocalVersion_WorkspaceName;

        public string UpdateWorkspace_OldWorkspaceName;
        public Workspace UpdateWorkspace_OriginalWorkspace;
        public string UpdateWorkspace_Owner;
        public Workspace UpdateWorkspace_UpdatedWorkspace;
        string url;

        public BranchRelative[][] QueryBranches_Result;
        public string QueryBranches_WorkspaceName;
        public string QueryBranches_WorkspaceOwner;
        public ItemSpec[] QueryBranches_Items;
        public VersionSpec QueryBranches_Version;

        public StubRepositoryWebSvc()
        {
            Get_Result.Add(new GetOperation(1, @"c:\Bar\file.txt", @"c:\Bar\file.txt", "$/Foo/file.txt", ItemType.File, "a=b&c=d", 1, 2));
            Get_Result.Add(new GetOperation(2, @"c:\Bar", @"c:\Bar", "$/Foo", ItemType.Folder, "a=b&c=d", 1, 2));

            GetRepositoryProperties__Result = new RepositoryProperties();
            GetRepositoryProperties__Result.lcset = 42;

            PendChanges_Failures = new Failure[0];
            PendChanges_Result = new GetOperation[1] { new GetOperation(1, "srcLocalItem", "tgtLocalItem", "srvItem", ItemType.File, "durl", 2, 3) };

            Change change = new Change();
            change.Item = new Item(1, 2, "durl", ItemType.File, "$/Foo/bar.txt");
            change.type = ChangeType.Add | ChangeType.Edit | ChangeType.Encoding;
            Changeset changeset = new Changeset();
            changeset.Changes = new Change[1] { change };
            changeset.cset = 42;
            changeset.date = DateTime.Now;
            changeset.cmtr = "owner";
            changeset.Comment = "Comment";
            QueryHistory_Result = new Changeset[1] { changeset };

            QueryItems_Result = new ItemSet[1] { new ItemSet() };
            QueryItems_Result[0].Items = new Item[] { new Item(1, 2, "3", ItemType.File, "4"), new Item(5, 6, "7", ItemType.Folder, "8") };

            QueryItemsById_Result = QueryItems_Result[0].Items;

            QueryWorkspaces_Result = new Workspace[] { new Workspace("foobar", "FakeComputer", "FakeOwner", "FakeComment") };

            UndoPendingChanges_Failures = new Failure[0];
            UndoPendingChanges_Result = new GetOperation[1] { new GetOperation(1, "srcLocalItem", "tgtLocalItem", "srvItem", ItemType.File, "durl", 2, 3) };

            UpdateWorkspace_OriginalWorkspace = new Workspace("foobar", "FakeComputer", "FakeOwner", "FakeComment");
            UpdateWorkspace_OriginalWorkspace.Folders = new WorkingFolder[1] { new WorkingFolder("$/bar", @"C:\Barbar", WorkingFolderType.Map) };

            CheckIn_Failures = new List<Failure>();
            CheckIn_Result = new CheckinResult();
            CheckIn_Result.cset = 84;
        }

        public ICredentials Credentials
        {
            get { return credentials; }
            set { credentials = value; }
        }

        public string Url
        {
            get { return url; }
            set { url = value; }
        }

        public CheckinResult CheckIn(string workspaceName,
                                     string ownerName,
                                     string[] serverItems,
                                     Changeset info,
                                     CheckinNotificationInfo checkinNotificationInfo,
                                     CheckinOptions checkinOptions,
                                     out Failure[] failures)
        {
            CheckIn_WorkspaceName = workspaceName;
            CheckIn_OwnerName = ownerName;
            CheckIn_ServerItems = new List<string>(serverItems);
            CheckIn_Info = info;
            CheckIn_CheckinNotificationInfo = checkinNotificationInfo;
            CheckIn_CheckinOptions = checkinOptions;

            failures = CheckIn_Failures.ToArray();
            return CheckIn_Result;
        }

        public Workspace CreateWorkspace(Workspace workspace)
        {
            CreateWorkspace_Workspace = workspace;
            if (CreateWorkspace_Throw != null)
                throw CreateWorkspace_Throw;

            return workspace;
        }

        public void DeleteWorkspace(string workspaceName,
                                    string ownerName)
        {
            DeleteWorkspace_WorkspaceName = workspaceName;
            DeleteWorkspace_Owner = ownerName;
        }

        public GetOperation[][] Get(string workspaceName,
                                    string ownerName,
                                    GetRequest[] requests,
                                    bool force,
                                    bool noGet)
        {
            Get_WorkspaceName = workspaceName;
            Get_OwnerName = ownerName;
            Get_GetRequests = requests;
            Get_Force = force;
            Get_NoGet = noGet;

            return new GetOperation[][] { Get_Result.ToArray() };
        }

        public RepositoryProperties GetRepositoryProperties()
        {
            return GetRepositoryProperties__Result;
        }

        public GetOperation[] PendChanges(string workspaceName,
                                          string ownerName,
                                          ChangeRequest[] changes,
                                          out Failure[] failures)
        {
            PendChanges_WorkspaceName = workspaceName;
            PendChanges_OwnerName = ownerName;
            PendChanges_Changes = changes;

            failures = PendChanges_Failures;
            return PendChanges_Result;
        }

        public Changeset[] QueryHistory(string workspaceName,
                                        string workspaceOwner,
                                        ItemSpec itemSpec,
                                        VersionSpec versionItem,
                                        string user,
                                        VersionSpec versionFrom,
                                        VersionSpec versionTo,
                                        int maxCount,
                                        bool includeFiles,
                                        bool generateDownloadUrls,
                                        bool slotMode)
        {
            QueryHistory_WorkspaceName = workspaceName;
            QueryHistory_WorkspaceOwner = workspaceOwner;
            QueryHistory_ItemSpec = itemSpec;
            QueryHistory_VersionItem = versionItem;
            QueryHistory_User = user;
            QueryHistory_VersionFrom = versionFrom;
            QueryHistory_VersionTo = versionTo;
            QueryHistory_MaxCount = maxCount;
            QueryHistory_IncludeFiles = includeFiles;
            QueryHistory_GenerateDownloadUrls = generateDownloadUrls;
            QueryHistory_SlotMode = slotMode;

            return QueryHistory_Result;
        }

        public ItemSet[] QueryItems(string workspaceName,
                                    string workspaceOwner,
                                    ItemSpec[] items,
                                    VersionSpec version,
                                    DeletedState deletedState,
                                    ItemType itemType,
                                    bool generateDownloadUrls)
        {
            QueryItems_WorkspaceName = workspaceName;
            QueryItems_Owner = workspaceOwner;
            QueryItems_Items = items;
            QueryItems_Version = version;
            QueryItems_DeletedState = deletedState;
            QueryItems_ItemType = itemType;
            QueryItems_GenerateDownloadUrls = generateDownloadUrls;

            return QueryItems_Result;
        }

        public Item[] QueryItemsById(int[] itemIds,
                                     int changeSet,
                                     bool generateDownloadUrls)
        {
            QueryItemsById_ItemIds = itemIds;
            QueryItemsById_ChangeSet = changeSet;
            QueryItemsById_GenerateDownloadUrls = generateDownloadUrls;

            return QueryItemsById_Result;
        }

        public Workspace QueryWorkspace(string workspaceName,
                                        string ownerName)
        {
            QueryWorkspace_WorkspaceName = workspaceName;
            QueryWorkspace_Owner = ownerName;

            return UpdateWorkspace_OriginalWorkspace;
        }

        public Workspace[] QueryWorkspaces(string ownerName,
                                           string computer)
        {
            QueryWorkspaces_Owner = ownerName;
            QueryWorkspaces_Computer = computer;

            return QueryWorkspaces_Result;
        }

        public GetOperation[] UndoPendingChanges(string workspaceName,
                                                 string ownerName,
                                                 ItemSpec[] items,
                                                 out Failure[] failures)
        {
            UndoPendingChanges_WorkspaceName = workspaceName;
            UndoPendingChanges_OwnerName = ownerName;
            UndoPendingChanges_Items = items;

            failures = UndoPendingChanges_Failures;
            return UndoPendingChanges_Result;
        }

        public void UpdateLocalVersion(string workspaceName,
                                       string ownerName,
                                       LocalVersionUpdate[] updates)
        {
            UpdateLocalVersion_WorkspaceName = workspaceName;
            UpdateLocalVersion_OwnerName = ownerName;
            UpdateLocalVersion_Updates = updates;
        }

        public Workspace UpdateWorkspace(string oldWorkspaceName,
                                         string ownerName,
                                         Workspace newWorkspace)
        {
            UpdateWorkspace_UpdatedWorkspace = newWorkspace;
            UpdateWorkspace_OldWorkspaceName = oldWorkspaceName;
            UpdateWorkspace_Owner = ownerName;

            return newWorkspace;
        }

        public BranchRelative[][] QueryBranches(string workspaceName, string workspaceOwner, ItemSpec[] items, VersionSpec version)
        {
            QueryBranches_WorkspaceName = workspaceName;
            QueryBranches_WorkspaceOwner = workspaceOwner;
            QueryBranches_Items = items;
            QueryBranches_Version = version;

            return QueryBranches_Result;
        }
    }
}